package com.gipson.amc.service.basicdata;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsbj.common.msg.ResponseMessage;
import com.gipson.amc.entity.*;
import com.gipson.amc.mapper.CompanyMapper;
import com.gipson.amc.mapper.UserMapper;
import com.gipson.amc.mapper.UserPostGroupMapper;
import com.gipson.amc.mapper.UserRoleMapper;
import com.gipson.amc.model.request.LoginRequest;
import com.gipson.amc.model.request.UserRequest;
import com.gipson.amc.utils.Constants;
import com.gipson.amc.utils.PasswordHelper;
import com.gipson.amc.utils.security.ShiroUtils;
import com.gipson.amc.utils.strprocess.ArrayUtil;
import com.gipson.amc.utils.strprocess.CamelUnderlineProcess;
import com.gipson.amc.utils.strprocess.StrUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author xsyuan
 * @since 2020-03-27
 */
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    @Autowired
    private PasswordHelper passwordHelper;

    @Autowired
    private AuthorityService authorityService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private UserPostGroupMapper userPostGroupMapper;
    
    @Autowired
    private CompanyMapper companyMapper;
    
    public Page<User> getUserPage(int pageindex, int pagesize,String username,String name){
        Page<User> page=new Page<User>().setCurrent(pageindex).setSize(pagesize);
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>()
                .like(StringUtils.isNotBlank(username),"USERNAME",username)
                .like(StringUtils.isNotBlank(name),"NAME",name)
                .orderByAsc("USER_CODE");
        baseMapper.selectPage(page,queryWrapper);
        return page;
    }

    public Page<User> selectPageForUser(User user,PageByDataTable pageByDataTable){
        Page<User> page=new Page<User>().setSize(pageByDataTable.getPagesize()).setCurrent(pageByDataTable.getPageindex());
        return baseMapper.queryPageData(page,user,pageByDataTable);
    }

    public User findUserByName(String username) {
        if(StringUtils.isEmpty(username)) return null;
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>()
                .eq("USERNAME",username);
        return getOne(queryWrapper);
    }

    public User findUserByUserId(String id) {
        return baseMapper.findUserByUserId(id);
    }

    /**
     * 根据user获取user列表。
     *
     * @param
     * @return
     * @author cjw 2020-05-20
     */
    public List<User> getUserByUser(User user) {
        List<User> list_user = baseMapper.findUserByUser(user);
        return list_user;
    }
    
    /**
     * @description 通过ID查询
     * @param
     * @author: xsyuan 2020/7/7 10:43
     * @return
     */
    public User getById(String id){
        User user = baseMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getId,id).eq(User::getDelFlag,0));
        if(user != null){
            if(StringUtils.isNotBlank(user.getCompanyCode())){
                Company company = companyMapper.selectOne(Wrappers.<Company>lambdaQuery().eq(Company::getCompanyCode,user.getCompanyCode()).eq(Company::getDelFlag,0));
                user.setCompanyName(company.getCompanyName());
            }
            
        }else{
            user = new User();
        }
        return user;
    }
    
    /**
     * 分页获取user信息。
     *
     * @param
     * @return
     * @author cjw 2020-05-20
     */
    public Page<User> getUserByPage(UserRequest userRequest) {
        Page<User> page = new Page<User>().setSize(userRequest.getPagesize()).setCurrent(userRequest.getPageindex());
        //ordercolumn
        if (StrUtil.isNotEmpty(userRequest.getOrdercolumn())) {
            String ordercolumn = CamelUnderlineProcess.camelToUnderlineWithUpperCase(userRequest.getOrdercolumn());
            userRequest.setOrdercolumn(ordercolumn);
        }
        baseMapper.findByPage(page, userRequest);
        return page;
    }
    
    /**
     * 根据userIdList获取user列表。
     *
     * @param
     * @return
     * @author cjw 2020-06-03
     */
    public List<User> getUserByIdList(List<String> userIdList) {
        if (ArrayUtil.isEmpty(userIdList)) {
            return new ArrayList<>();
        }
        List<User> userList = baseMapper.selectBatchIds(userIdList);
        return userList;
    }
    
    /**
     * 删除
     * @param ids
     */
    public ResponseMessage delBatch(String ids){
        String[] idStr = ids.split(",");
        List<String> idList = Arrays.asList(idStr);
        List<User> userList = baseMapper.selectBatchIds(idList);
        List<String> deleteByIds = new ArrayList<>();
        String sysUser = "";//系统用户
        for (User user : userList){
            if(user.getSysFlag()==1){
                sysUser+=user.getName()+"\n";
            }
            deleteByIds.add(user.getId());
        }
        if(StringUtils.isNotBlank(sysUser)){
            return ResponseMessage.error("姓名："+sysUser+",为系统账户，不能删除！");
        }else{
            //1.删除用户角色
            userRoleMapper.deleteByUserIds(idStr);
            //2.删除用户岗位
            userPostGroupMapper.deleteByUserIds(idStr);
            //3.删除用户
            baseMapper.deleteBatchIds(deleteByIds);
            return ResponseMessage.ok("删除成功");
        }
    }
    @Transactional
    public void addUser(User user) {
        save(user);
    }
    @Transactional
    public ResponseMessage saveOrUpdateByUser(User user,String roleIds,String postGroupIds) {
        User currentUser = ShiroUtils.getCurrentUser();
        if(StringUtils.isNotBlank(user.getId())){
            user.setUpdateUser(currentUser.getId());
            user.setUpdateTime(new Date());
            updateById(user);
            addUserRole(user,roleIds);
            addUserPostGroup(user,postGroupIds);
            return ResponseMessage.ok("修改成功");
        }else{
            List<User> checkUserName = list(Wrappers.<User>lambdaQuery().eq(User::getUsername,user.getUsername()));
            String msg = "";
            //判断用户名是否重复
            if(CollectionUtils.isNotEmpty(checkUserName)){
                msg = "用户名已存在！";
                return ResponseMessage.error(msg);
            }
            user.setPassword(user.getUsername());
            passwordHelper.encryptPassword(user);
            user.setCreateUser(currentUser.getId());
            user.setCreateTime(new Date());
            save(user);
            addUserRole(user,roleIds);
            addUserPostGroup(user,postGroupIds);
            return ResponseMessage.ok("新增成功");
        }
    }
    
    @Transactional
    public ResponseMessage saveByPassword(String amcOldPassword,String amcNewPassword) {
        if(StringUtils.isNotBlank(amcOldPassword)){
            if(StringUtils.isNotBlank(amcNewPassword)){
                User user = ShiroUtils.getCurrentUser();
                String oldPassword = new SimpleHash(PasswordHelper.ALGORITHM_NAME,amcOldPassword,
                        ByteSource.Util.bytes(user.getSalt()), PasswordHelper.HASH_ITERATIONS).toHex();
                if(!user.getPassword().equals(oldPassword)){
                    return ResponseMessage.error("密码不对!");
                }
                String newPassword = new SimpleHash(PasswordHelper.ALGORITHM_NAME, amcNewPassword,
                        ByteSource.Util.bytes(user.getSalt()), PasswordHelper.HASH_ITERATIONS).toHex();
                user.setPassword(newPassword);
                updateById(user);
                return ResponseMessage.ok("修改成功") ;
            }
            return ResponseMessage.error("新密码不能为空");
        }
        return ResponseMessage.error("原密码不能为空");
    }

    @Transactional
    public ResponseMessage updateByPassword(User user) {
        if(StringUtils.isNotBlank(user.getPassword())){
            if(StringUtils.isNotBlank(user.getNewPassWord())){
                User findUser = baseMapper.selectOne(new QueryWrapper<User>().eq("USERNAME",user.getUsername())
                        .eq("DEL_FLAG",0));
                if(findUser != null){
                    String oldPassword = new SimpleHash(PasswordHelper.ALGORITHM_NAME, user.getPassword(),
                            ByteSource.Util.bytes(findUser.getSalt()), PasswordHelper.HASH_ITERATIONS).toHex();
                    if(!findUser.getPassword().equals(oldPassword)){
                        return ResponseMessage.error("密码不对!");
                    }
                    String newPassword = new SimpleHash(PasswordHelper.ALGORITHM_NAME, user.getNewPassWord(),
                            ByteSource.Util.bytes(findUser.getSalt()), PasswordHelper.HASH_ITERATIONS).toHex();
                    user.setPassword(newPassword);
                    updateById(user);
                    return ResponseMessage.ok("修改成功");
                }else{
                    return ResponseMessage.ok("用户名不存在");
                }
            }
            return ResponseMessage.error("新密码不能为空");
        }
        return ResponseMessage.error("原密码不能为空");
    }
 /**
   * @description 新增用户角色
   * @param
   * @author: xsyuan 2020/5/21 17:32
   * @return
   */
    private void addUserRole(User user,String roleIds){
        Map<String ,Object> deleteByUserId = new HashMap<>();
        deleteByUserId.put("USER_ID",user.getId());
        userRoleMapper.deleteByMap(deleteByUserId);
        if(StringUtils.isNotBlank(roleIds)){
            String[] roleIdStr = roleIds.split(",");
            UserRole role = new UserRole();
            role.setUserId(user.getId());
            for (int i = 0 ;i < roleIdStr.length;i++){
                role.setRoleId(roleIdStr[i]);
                userRoleMapper.insert(role);
            }
        }
    }
    
 /**
   * @description  新增用户岗位
   * @param
   * @author: xsyuan 2020/5/21 17:33
   * @return
   */
    private void addUserPostGroup(User user,String postGroupIds){
        Map<String ,Object> deleteByUserId = new HashMap<>();
        deleteByUserId.put("USER_ID",user.getId());
        userPostGroupMapper.deleteByMap(deleteByUserId);
        if(StringUtils.isNotBlank(postGroupIds)){
            String[] postGroupIdStr = postGroupIds.split(",");
            UserPostGroup userPostGroup = new UserPostGroup();
            userPostGroup.setUserId(user.getId());
            for (int i = 0 ;i < postGroupIdStr.length;i++){
                userPostGroup.setPostGroupId(postGroupIdStr[i]);
                userPostGroupMapper.insert(userPostGroup);
            }
        }
    }

    public ResponseMessage authCredentials(LoginRequest loginRequest) {
        User user = findUserByName(loginRequest.getUsername());

        if(user==null){
            return ResponseMessage.error(Constants.NETWORK_STATE_USER_NOT_EXIST,"用户不存在!");
        }

        if(user.getUsername().equals("admin")){
            return ResponseMessage.error(Constants.NETWORK_STATE_USER_NOT_EXIST,"用户不存在!");
        }

        String calcPassword = new SimpleHash(PasswordHelper.ALGORITHM_NAME, loginRequest.getPassword(), ByteSource.Util.bytes(user.getSalt()), PasswordHelper.HASH_ITERATIONS).toHex();
        if(!user.getPassword().equals(calcPassword)){
            return ResponseMessage.error(Constants.NETWORK_STATE_INVALID_PASSWORD,"用户名密码错误!");
        }
        user.setPassword("");
        user.setSalt("");

        user.setMenus(authorityService.getAllMenuByUsername(user.getUsername(),loginRequest.getApplicationId()));

        user.setRoleCodes(new ArrayList<>());
        user.setAuthorityCodes(new ArrayList<>());
        List<Role> roleList = roleService.getRolesByUsername(user.getUsername());

        for (Role role : roleList) {
            user.getRoleCodes().add(role.getRoleCode());
            List<Authority> authorities = authorityService.listByRoleId(role.getId());
            authorities.stream().filter(x->Authority.TYPE_PERMISSON.equals(x.getType())).forEach(x-> {
                if(!user.getAuthorityCodes().contains(x.getPermission())){
                    user.getAuthorityCodes().add(x.getPermission());
                }
            });
        }

        return ResponseMessage.ok(user);
    }

    /**
     * 根据ids获取user信息。
     * @param ids
     * @return
     */
    public ResponseMessage listUserByIds(List<String> ids) {
        //StrUtil.prettyPrint("ids", ids);
        return ResponseMessage.ok(baseMapper.selectBatchIds(ids));
    }

    public Map<String, User> mapUserByIds(List<String> ids) {
        ResponseMessage<List<User>> responseMessage_temp = listUserByIds(ids);
        if (responseMessage_temp.isSuccess() == false || responseMessage_temp.getData() == null) {
            throw new RuntimeException("根据ids获取用户信息时,出错!" + responseMessage_temp.toString());
        }
        List<User> userList = responseMessage_temp.getData();
        return userList.stream().collect(Collectors.toMap(User::getId, user -> user));
    }

}
